package com.yanqu.road.dao.db;

import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;
import com.jolbox.bonecp.Statistics;
import com.yanqu.road.utils.executor.ScheduledThreadPoolHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @功能 :数据库类连接池
 */
public class BoneCPPool {
    private static final Logger logger = LogManager.getLogger(BoneCPPool.class.getName());

    private static ScheduledExecutorService DBPoolStat = ScheduledThreadPoolHelper.createGameScheduledThreadPoolExecutor(1,
            "DBPoolMonitor");

    BoneCP connectionPool = null;
    BoneCPConfig config = null;

    public BoneCPPool(String poolName, String dbConnUrl, String dbUserName, String dbPassWord, int maxConn,
                      int partitionCount, int maxConnPerPart, int minConnPerPart) {
        config = new BoneCPConfig();
        config.setJdbcUrl(dbConnUrl);
        config.setUsername(dbUserName);
        config.setPassword(dbPassWord);
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (Exception e1) {
            logger.error(e1.getMessage(), e1);
        }

        int idle = DBPoolManager.getPropertiesFile().getProperty("idleConnectionTestPeriod") == null ? 3 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("idleConnectionTestPeriod")) ; config.setIdleConnectionTestPeriodInMinutes(idle);
        int idleMaxAge = DBPoolManager.getPropertiesFile().getProperty("IdleMaxAgeInMinutes") == null ? 5 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("IdleMaxAgeInMinutes")) ; config.setIdleMaxAgeInMinutes(idleMaxAge);
        boolean statisticsEnabled = DBPoolManager.getPropertiesFile().getBoolean("StatisticsEnabled", true);
        int acquireIncrement = DBPoolManager.getPropertiesFile().getProperty("AcquireIncrement") == null ? 5 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("AcquireIncrement"));config.setAcquireIncrement(acquireIncrement);
        int releaseHelperThreads = DBPoolManager.getPropertiesFile().getProperty("releaseHelperThreads") == null ? 4 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("releaseHelperThreads"));config.setReleaseHelperThreads(releaseHelperThreads);
        int connectionTimeoutInMs = DBPoolManager.getPropertiesFile().getProperty("CloseConnectionWatchTimeout") == null ? 60000 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("CloseConnectionWatchTimeout"));config.setConnectionTimeoutInMs(connectionTimeoutInMs);config.setCloseConnectionWatch(false);
        int closeConnectionWatchTimeoutInMs = DBPoolManager.getPropertiesFile().getProperty("ConnectionTimeout") == null ? 60 * 1000 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("ConnectionTimeout"));config.setCloseConnectionWatchTimeoutInMs(closeConnectionWatchTimeoutInMs);

        if (!dbConnUrl.contains("servercenter") && !dbConnUrl.contains("config") && !dbConnUrl.contains("cross")) {
            partitionCount = DBPoolManager.getPropertiesFile().getProperty("partitionCount") == null ? 4 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("partitionCount"));
            maxConnPerPart = DBPoolManager.getPropertiesFile().getProperty("maxConnectionsPerPartition") == null ? 10 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("maxConnectionsPerPartition"));
            minConnPerPart = DBPoolManager.getPropertiesFile().getProperty("minConnectionsPerPartition") == null ? 1 : Integer.valueOf(DBPoolManager.getPropertiesFile().getProperty("minConnectionsPerPartition"));
        }


        config.setIdleMaxAgeInMinutes(idleMaxAge);
        config.setIdleConnectionTestPeriodInMinutes(idle);
        config.setAcquireIncrement(acquireIncrement);
        config.setStatisticsEnabled(statisticsEnabled);
        config.setPartitionCount(partitionCount);
        config.setMinConnectionsPerPartition(minConnPerPart);
        config.setMaxConnectionsPerPartition(maxConnPerPart);
        config.setConnectionTimeoutInMs(10000);
        if (dbConnUrl.contains("servercenter")) {
            config.setMaxConnectionAge(0, TimeUnit.MINUTES);
        } else {
            config.setMaxConnectionAge(240, TimeUnit.MINUTES);
        }
        config.setLazyInit(true);

        try {
            connectionPool = new BoneCP(config);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

    public void shutDownBoneCpDbPoll() {
        if (connectionPool != null) {
            connectionPool.close();
        }
    }

    public Connection getDbConnection() {
        try {
            return connectionPool.getConnection();
        } catch (SQLException ex) {
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

}
